package com.ruoyi.outpatient.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.constant.PersonConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.outpatient.core.SecurityUtils;
import com.ruoyi.outpatient.domain.Blog;
import com.ruoyi.outpatient.domain.Person;
import com.ruoyi.outpatient.domain.Reply;
import com.ruoyi.outpatient.domain.Tag;
import com.ruoyi.outpatient.mapper.IBlogMapper;
import com.ruoyi.outpatient.mapper.ITagMapper;
import com.ruoyi.outpatient.service.ITagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Array;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import static com.ruoyi.common.utils.PageUtils.startPage;
import static java.util.stream.Collectors.toList;

/**
 * @author 伟峰
 * @date 2022/4/25
 * @description:
 */
@Service
public class TagServiceImpl implements ITagService {

    @Autowired
    private ITagMapper tagMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IBlogMapper blogMapper;

    @Autowired
    private SecurityUtils securityUtils;

    @Override
    public AjaxResult selectNewTagList(Tag tag) {


        startPage();
//        根据最新的tagid查询blog集合 tagName time
//        2.tag和主题包含的(篮球)然后取并集返回
        List<Tag> list=tagMapper.selectNewBlogListByTagId(tag);



        // TODO: 2022/4/25 滚动翻页 
        return AjaxResult.success().put("list",list);
    }

    /**
     * 通过tag检索最热门 帖子浏览量排序 （tagName要包含标签和主题）
     * @param tag tagId+tagName
     * @return list
     */
    @Override
    public AjaxResult selectBlogListByTagName(String tagName) {

//        1.redis查找

//        2.数据库查找
//            2.1 找出帖子带有%tagName%的 主题 最多的访问量的（blog集合）
        List<Blog> blogList=blogMapper.selectBlogListByTagName(tagName);

//            2.2 找出tag含有tagName的（blog集合）
       List<Tag> tags= tagMapper.selectBlogListByTagName(tagName);


//        1.将List<Tag>中blog集合转为List<Blog>
        List<Blog> collect2 = tags.stream().map(Tag::getBlog).collect(toList());
//        2.然后两个List<Blog>进行合并
        blogList.addAll(collect2);
//        3.将合并后集合中blogid相同的进行 去重
        List<Blog> collect = blogList.stream().collect(
                Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Blog::getBlogId))), ArrayList::new)
        );
//       4.合并好后按照浏览量排序返回
        List<Blog> bloged = collect.stream().sorted(Comparator.comparing(Blog::getPageView).reversed()).collect(toList());



        Long loginPersonId = securityUtils.getLoginPersonId();
        //        基于内容推荐算法 当用户搜索某个标签时,log(标签排名^标签分数)+标签分数 来进行增加
        // TODO: 2022/5/15 不需要基于内容推介，按点赞+收藏+标签

//        1.开启redis事务,为了只用一次性连接通道
//        3.查出该tagName的排名 O(logN)
        Long ranking=redisCache.reverseRankZset(PersonConstants.RECOMMEND_TAGSCORE+loginPersonId,tagName);
        if (ranking==null){
//            如果获取的标签,用户没有则添加
            redisCache.incrementScoreZset("recommend:tagscore:"+loginPersonId,tagName,1);
        }else {
            double rank = ranking.doubleValue();
//        4.查出tagName中的分数 O（1）
            double score = redisCache.getCacheZSetScore("recommend:tagscore:" + loginPersonId, tagName);
//        5.计算出 log(x^y)即ranking和score
//        以排名为底数,tag分数取平方,这样就可以分数越高增长越慢 + 原来的分数
            double tagNameScore = Math.log(Math.pow(rank, score))+score;
//        6.将分数加入
            redisCache.MysetCacheZSet("recommend:tagscore:" + loginPersonId, tagName,tagNameScore);
//        log(rank, score)
//           排名为底数 分数为y
        }


//        放到MQ中
//        用户搜索的 历史记录 超过10个就将第11个删除  一个月后过期
        Long cacheZSetZCard = redisCache.getCacheZSetZCard("history:tag" + loginPersonId);
        if (cacheZSetZCard<=10){
            redisCache.setCacheZSet("history:tag"+loginPersonId,tagName,System.currentTimeMillis());
        }else {
            redisCache.setCacheZSet("history:tag"+loginPersonId,tagName,System.currentTimeMillis());
//            将第11个移除
            redisCache.removeRangeZSet("history:tag"+loginPersonId,11L,11L);
        }




//        todo 后期需加上热门比重去除
        return AjaxResult.success().put("blog",bloged);
    }


    /**
     * 通过标签搜索 综合排序
     * @param tagName
     * @return
     */
    @Override
    public AjaxResult selectComprehenBlogList(String tagName) {


//        Long loginPersonId = securityUtils.getLoginPersonId();



//        SELECT b.`blog_id`,b.`blog_image`,b.`blog_theme`,b.`page_view`,t.tag_name,b.`page_view`,b.likes,b.comments_sum
//        FROM tag t LEFT JOIN blog_tag bt ON t.tag_id=bt.tag_id
//        LEFT JOIN blog b ON bt.blog_id=b.`blog_id`
//        WHERE t.tag_name LIKE "%篮%" OR b.`blog_theme` LIKE "%篮%" GROUP BY b.blog_id ORDER BY b.`page_view` DESC




////        基于内容推荐算法 当用户搜索某个标签时,log(标签排名^标签分数)+标签分数 来进行增加
//        //  2022/5/15 不需要基于内容推介，按点赞+收藏+标签
//
////        1.开启redis事务,为了只用一次性连接通道
////        3.查出该tagName的排名 O(logN)
//        Long ranking=redisCache.reverseRankZset(PersonConstants.RECOMMEND_TAGSCORE+loginPersonId,tagName);
//        double rank = ranking.doubleValue();
////        4.查出tagName中的分数 O（1）
//        double score = redisCache.getCacheZSetScore("recommend:tagscore:" + loginPersonId, tagName);
////        5.计算出 log(x^y)即ranking和score
////        以排名为底数,tag分数取平方,这样就可以分数越高增长越慢 + 原来的分数
//        double tagNameScore = Math.log(Math.pow(rank, score))+score;
////        6.将分数加入
//        redisCache.MysetCacheZSet("recommend:tagscore:" + loginPersonId, tagName,tagNameScore);
//
////        log(rank, score)
////           排名为底数 分数为y
//
//
//
////        放到MQ中
////        用户搜索的 历史记录 超过10个就将第11个删除  一个月后过期
//        Long cacheZSetZCard = redisCache.getCacheZSetZCard("history:tag" + loginPersonId);
//        if (cacheZSetZCard<=10){
//            redisCache.setCacheZSet("history:tag"+loginPersonId,tagName,System.currentTimeMillis());
//        }else {
//            redisCache.setCacheZSet("history:tag"+loginPersonId,tagName,System.currentTimeMillis());
////            将第11个移除
//            redisCache.removeRangeZSet("history:tag"+loginPersonId,11L,11L);
//        }





        return null;
    }



    /**
     * 后台 查询tag列表
     * @param tag
     * @return
     */
    @Override
    public List<Tag> selectGTagList(Tag tag) {
        return tagMapper.selectGTagList(tag);
    }


    /**
     * 后台根据id删除tag列表
     * @param tagIds
     * @return
     */
    @Override
    public int deleteGTagByIds(Long[] tagIds) {
        return tagMapper.deleteTagByIds(tagIds);

    }

    /**
     * 后台删除tag
     * @param tag
     * @return
     */
    @Override
    public int insertGTag(Tag tag) {
        return tagMapper.insertGTag(tag);
    }


    /**
     * 后台更新tag
     * @param tag
     * @return
     */
    @Override
    public int updateGTag(Tag tag) {
        return tagMapper.updateGTag(tag);
    }
}
